package com.iss.examsys.ejb;

import com.iss.examsys.entity.User;
import java.io.Serializable;
import java.security.MessageDigest;
import javax.ejb.EJB;
import javax.enterprise.context.SessionScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;

@SessionScoped
@Named
public class UserSessionBean implements Serializable  {
    private static final long serialVersionUID = 1L;
	
	private String name="";
	private String password="";
        private String newPassword="";

        private String[] roles = new String[]{"admins","students","lecturers"};
        private boolean hasLoggedIn = false;
        
        @PersistenceContext EntityManager em;
        @EJB UserBean userBean;

	public String getName() {
		return (name);
	}
	public void setName(String name) {		
		this.name = name;
	}

	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}

        public String getNewPassword() {
            return newPassword;
        }

        public void setNewPassword(String newPassword) {
            this.newPassword = newPassword;
        }
     
	public String login() {
		ExternalContext ctx = FacesContext.getCurrentInstance()
				.getExternalContext();
		HttpServletRequest req = (HttpServletRequest)ctx.getRequest();
		
		try {
			req.login(name, password);
		} catch (ServletException ex) {
			try { req.logout(); } catch (ServletException e) { }
			return ("/faces/auth/invalid_login.xhtml");
		}
//		User user = findUserByUserId();
//                if(user!=null){
//                    if(user.getVersion().equalsIgnoreCase("1")){
//                        return ("/faces/auth/newUsers.xhtml");
//                    }
//                }
                
                hasLoggedIn = true;
                String authenticationAccess = userBean.getAccessAuthentication();
		return authenticationAccess;
	}
	
	
	public String logout() {
		ExternalContext ctx = FacesContext.getCurrentInstance()
				.getExternalContext();
		HttpServletRequest req = (HttpServletRequest)ctx.getRequest();
		req.getSession().invalidate();
                hasLoggedIn=false;
		return ("/faces/welcome.xhtml");
	}
        
        public User findUserByUserId(){
            TypedQuery<User> result = em.createNamedQuery("User.findByUserId", User.class);
            result.setParameter("userId", name);
                    
            if(result.getResultList().size()>0){
                    return result.getResultList().get(0);
            }
            
            return null;
        }
        
        public String createNewPassword(){
            if(!password.equalsIgnoreCase(newPassword)){
                User user = findUserByUserId();
                
                String edittedPassword = sha256(newPassword);         
                user.setPassword(edittedPassword);
                
                int versionNo = Integer.valueOf(user.getVersion());
                versionNo++;
                user.setVersion(String.valueOf(versionNo));
                
                userBean.edit(user);
                
                
                hasLoggedIn = true;
                String authenticationAccess = userBean.getAccessAuthentication();
                return authenticationAccess;
            }
            
            return ("/faces/auth/newUsers.xhtml");
        }
        
        public boolean isUserLogIn(){
            return hasLoggedIn;
        }
        
        public String findRoleByUserId(String userId){
            ExternalContext ctx = FacesContext.getCurrentInstance()
                .getExternalContext();
 
            String role="";
            
            for(int i=0;i<roles.length;i++){
                role = roles[i];
                
                if(ctx.isUserInRole(role)){
                    break;
                }
                
            }
            return role;
        }
        
        public String getAccessAuthentication(){
            
//            TypedQuery<UserGroup> result = em.createNamedQuery("UserGroup.findByUserId", UserGroup.class);
//            result.setParameter("userId", name);
            
            String role = findRoleByUserId(name);

            switch (role){
                case "admins": return "/faces/menu/admin/menu.xhtml";
                case "lecturers": return "/faces/menu/lecturer/menu.xhtml";
                case "students": return "/faces/examsession/examList.xhtml";
                default: return "";
            }
        }
        
    private static String sha256(String base) {
        try{
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] hash = digest.digest(base.getBytes("UTF-8"));
            StringBuffer hexString = new StringBuffer();

            for (int i = 0; i < hash.length; i++) {
                String hex = Integer.toHexString(0xff & hash[i]);
                if(hex.length() == 1) hexString.append('0');
                hexString.append(hex);
            }

            return hexString.toString();
        } catch(Exception ex){
            throw new RuntimeException(ex);
        }
}
}
